{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# get方法\n",
    "import requests\n",
    "\n",
    "url = \"http://www.baidu.com\"\n",
    "params = {\"\": \"\"}  # 可以带参数;在url里面为?后面的参数\n",
    "response = requests.get(url, params=params)\n",
    "print(response.status_code)  # 打印url的状态,返回200则为请求成功\n",
    "print(response.content)  # 返回html源码,返回值的b''表示是二进制的数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 解码content\n",
    "import requests\n",
    "\n",
    "url = \"http://www.baidu.com\"\n",
    "response = requests.get(url)\n",
    "print(response.content.decode(\"utf-8\"))  # 返回html源码,返回值的b''表示是二进制的数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# TCP服务端\n",
    "import socket\n",
    "\n",
    "serverSocket = socket.socket(\n",
    "    socket.AF_INET, socket.SOCK_STREAM\n",
    ")  # AF_INET是ipv4,SOCK_STREAM是tcp\n",
    "serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)  # 设置端口复用\n",
    "\n",
    "try:\n",
    "    serverSocket.bind(\n",
    "        (\"localhost\", 8000)\n",
    "    )  # 这里是一个元组参数,而不是两个参数;一般不要用1023及以前的端口号\n",
    "except Exception as e:\n",
    "    print(e)\n",
    "    serverSocket.close()\n",
    "\n",
    "serverSocket.listen(128)  # 128是最大连接数\n",
    "serverSocket.accept()  # 返回一个元组,第一个是连接的socket,第二个是连接的地址\n",
    "\n",
    "while True:\n",
    "    clientSocket, ServerIpPort = (\n",
    "        serverSocket.accept()\n",
    "    )  # 返回一个元组,第一个是连接的socket,第二个是连接的地址\n",
    "    # 这个ClientSocket是通过ServerSocket的accept方法返回的,不是通过socket.socket()创建的\n",
    "\n",
    "    data = clientSocket.recv(1024)  # 1024是最大接收字节数\n",
    "    print(\"服务器收到:\", format(data.decode(\"utf-8\")), ServerIpPort)  # recData需要解码\n",
    "\n",
    "    clientSocket.send(\n",
    "        \"HTTP/1.1 200 OK\\r\\nServer:OK\\r\\n\\r\\n<div>清文很帅</div>\".encode(\"utf-8\")\n",
    "    )  # 发送数据,需要编码\n",
    "    clientSocket.close()  # 关闭连接,防止内存泄漏"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 用requests访问TCP服务端\n",
    "import requests\n",
    "\n",
    "url = \"http://localhost:8000\"\n",
    "res = requests.get(url)\n",
    "print(res.content.decode(\"utf-8\"))  # 返回html源码,返回值的b''表示是二进制的数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建TCP客户端\n",
    "import socket\n",
    "\n",
    "clientSocket = socket.socket(\n",
    "    socket.AF_INET, socket.SOCK_STREAM\n",
    ")  # AF_INET是ipv4,SOCK_STREAM是tcp\n",
    "clientSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)  # 设置端口复用\n",
    "clientSocket.connect((\"localhost\", 8000))  # 也是一个元组\n",
    "\n",
    "clientSocket.send(\"哈哈\".encode(\"utf-8\"))  # 发送数据,需要编码\n",
    "data = clientSocket.recv(1024)\n",
    "print(data.decode(\"utf-8\"))\n",
    "clientSocket.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "服务端bind成功\n",
      "服务端收到: 谭清文很帅 ('127.0.0.1', 52037)\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[11], line 15\u001b[0m\n\u001b[1;32m     11\u001b[0m     serverSocket\u001b[38;5;241m.\u001b[39mclose()\n\u001b[1;32m     14\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m---> 15\u001b[0m     recData, ServerIpPort \u001b[38;5;241m=\u001b[39m \u001b[43mserverSocket\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrecvfrom\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m     16\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;241;43m1024\u001b[39;49m\n\u001b[1;32m     17\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m  \u001b[38;5;66;03m# 接收数据,返回一个元组,第一个是数据,第二个是地址\u001b[39;00m\n\u001b[1;32m     18\u001b[0m     recDataNature \u001b[38;5;241m=\u001b[39m recData\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mutf-8\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m     20\u001b[0m     \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m服务端收到:\u001b[39m\u001b[38;5;124m\"\u001b[39m, recDataNature, ServerIpPort)\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "# 创建UDP服务端\n",
    "import socket\n",
    "\n",
    "serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n",
    "serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)\n",
    "try:\n",
    "    serverSocket.bind((\"localhost\", 8080))  # 绑定端口\n",
    "    print(\"服务端bind成功\")\n",
    "except Exception as e:\n",
    "    print(e)\n",
    "    serverSocket.close()\n",
    "\n",
    "\n",
    "while True:\n",
    "    data, ServerIpPort = serverSocket.recvfrom(\n",
    "        1024\n",
    "    )  # 接收数据,返回一个元组,第一个是数据,第二个是地址\n",
    "    dataNature = data.decode(\"utf-8\")\n",
    "\n",
    "    print(\"服务端收到:\", dataNature, ServerIpPort)\n",
    "    serverSocket.sendto(\n",
    "        '服务端: 你好UDP客户端, 已收到你的发送的\"{}\"'.format(dataNature).encode(\n",
    "            \"utf-8\"\n",
    "        ),\n",
    "        ServerIpPort,\n",
    "    )  # 服务端发送数据"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
